<?php
require_once('wpfunctions.php');
require_once('psalmfunctions.php');
// KEYS that get saved in modern engravings
$engravingKeys = array_flip(array(
    'template',
    'tune',
    'text',
    'sop',
    'alt',
    'ten',
    'bas',
    'lyrics',
    'chords',
    'refrain',
    'refrainAtBeginning',
    'layout',
    'key',
    'transposekey',
    'filename',
    'name',
    'dir',
    'width',
    'height',
    'croppdf',
    'commentary',
    'user-notes',
    'annotation',
    'modeoffset',
    'meter',
    'author',
    'copyright',
    'suppressTimeSignature',
    'suppressStems',
    'raggedlast',
    'harmonization',
    'useTuneInFileName',
    'ignoreDurations',
    'separateVoices',
    'solidifyDashedSlurs',
    'hideDashedSlurs'
  ));
$numbers = array('One','Two','Three','Four','Five','Six','Seven','Eight','Nine','Ten');
function breakUpVerses(&$vars,$numVerses=10,$verseSeparators) {
  global $numbers;
  $refrain = $vars['refrain'];
  $refrainAtBeginning = $vars['refrainAtBeginning'];
  preg_match_all('/([^\r\n]+(?:\r?\n(?!\s*\n))?)+/',$vars['lyrics'],$matches, PREG_PATTERN_ORDER);
  preg_match_all('/([^\r\n]+(?:\r?\n(?!\s*\n))?)+/',$refrain,$refrainMatches, PREG_PATTERN_ORDER);
  $numRefrains = count($refrainMatches[0]);
  if($refrainAtBeginning) {
    if($refrain=='') {
      $refrain = array_shift($matches[0]);
      $vars['refrainBeforeVerseOne'] = applyLyricBoldItalics($refrain);
      $numRefrains = 1;
    } else {
      foreach($refrainMatches[0] as $i => $m) {
        $num = $numbers[$i];
        $vars["refrainBeforeVerse$num"] = applyLyricBoldItalics($m);
        if($i==0) $refrain = $m;
      }
      $numRefrains = count($refrainMatches[0]);
    }
  
    preg_match_all('/\S+(?:\s+--)?/',$refrain,$m);
    $refrainSylCount = count($m[0]);
    if($refrainSylCount > 0) {
      $i = $numRefrains;
      while($i < 10) {
        $num = $numbers[$i];
        $vars["refrainBeforeVerse$num"] = "\\repeat unfold $refrainSylCount \skip1";
        ++$i;
      }
    }
  }
  $actualNumVerses = min($numVerses,count($matches[0]));
  $midVerse = $actualNumVerses - $numRefrains;
  if(($midVerse % 2) == 1) {
    --$midVerse;
  }
  $midVerse /= 2;
  if($numRefrains>1) {
    $midVerse = 0;
  }
  $vars['extraverses'] = array();
  $vars['extraverseNumbers'] = array();
  $vars['extraverseNotes'] = array();
  foreach($matches[0] as $i => $m) {
    $number = $numbers[$i];
    $key = "verse$number";
    if(preg_match('/(?:^|\n)\[([^]]+)\]\s*\r?\n/', $m, $match)) {
      $m = str_replace($match[0], '', $m);
      $vars["verse{$number}Note"] = applyLyBoldItalics($match[1]);
      $verseNote = $match[1];
    } else {
      $verseNote = '';
    }
    if(preg_match('/(?:^|\n)\{([^}]+)\}\s*\r?\n/', $m, $match)) {
      $m = str_replace($match[0], '', $m);
      $vars["verse{$number}Number"] = applyLyBoldItalics($match[1]);
      $verseNumber = $match[1];
    } else {
      $verseNumber = '';
    }
    if($i >= $numVerses) {
      $vars['extraverseNotes'][]  = $verseNote;
      $vars['extraverseNumbers'][]  = $verseNumber;
      $vars["verse{$number}Note"] = '';
      $vars["verse{$number}Number"] = '';
      $vars['extraverses'][] = preg_replace('/\s+--\s+/','\-',
        preg_replace('/(^|\s)(?:""|_|__)(\s+|$)/','$1$2',
        preg_replace('/(^|\s)(?:""|_|__|\\\S*)(\s+|$)/','$1$2',$m)));
      continue;
    }
    if($i>=$midVerse && !$refrainAtBeginning && $numRefrains > ($i - $midVerse)) {
      $m .= "\n\n" . $refrainMatches[0][$i - $midVerse];
    }
    $vars[$key] = applyLyricBoldItalics($m);
  }
  return $actualNumVerses;
}
function applyLyBoldItalics($text) {
  $regBold = '/\|+(\\S(?:.*?(?:([a-z])|\\S))?)\|+/i';
  $regItalic = '/_+(\\S(?:.*?(?:([a-z])|\\S))?)_+/i';
  return preg_replace($regBold, '" \\bold"$1" "',
                 preg_replace($regItalic, '" \\italic"$1" "', $text));
}
function applyLyricBoldItalics($text) {
  $regBold = '/\|+(\\S+)\|+/i';
  $regItalic = '/_+(\\S+)_+/i';
  $regTie = '/(\\S+)⁀(\\S+)/';
  return preg_replace($regBold, '\\markup\\bold"$1"',
                 preg_replace($regItalic, '\\markup\\italic"$1"', 
                  preg_replace($regTie, '\\markup\\concat{$1 \\lower #1 ⁀ $2}', $text)));
}
function mergeTuneHarmonization(&$vars) {
  $tune = $vars['tune-data'];
  $vars['tuneCopyright'] = $tune['copyright'];
  $vars['harmCopyright'] = $vars['copyright'];
  $vars['filename'] = $tune['filename'];
  $vars['name'] = $tune['name'];
  $vars['key'] = $tune['key'];
  $vars['commentary'] = $tune['commentary'];
  $vars['user-notes'] = $tune['user-notes'];
  $vars['annotation'] = $tune['annotation'];
  $vars['meter'] = $tune['meter'];
  $vars['author'] = $tune['author'];
  $vars['sop'] = $tune['sop'];
  $vars['refrainAtBeginning'] = $tune['refrainAtBeginning'];
  $vars['raggedlast'] = $tune['raggedlast'];
  $vars['suppressTimeSignature'] = $tune['suppressTimeSignature'];
  $vars['suppressStems'] = $tune['suppressStems'];
  $vars['originalTemplate'] = $vars['template'];
  $vars['template'] = $tune['template'];
}
function getLy(&$vars,$addHeader=false,$addIncludeBook=false,$numVerses=10,$verseSeparators=Array()) {
  global $numbers;
  $template = $vars['template'];
  if($template=='hymn' || $template=='harmonization') {
    //Get Tune...
    $tune = $vars['tune-data'];
    $tuneDir = 'hymn-tunes';
    if(!$tune) {
      if($vars['template'] == 'hymn' && $vars['layout']!='melody') {
        $tuneDir = 'hymn-harmonizations';
      }
      $tune = loadLy("$tuneDir/{$vars['tune']}");
      $vars['tune-data'] = $tune;
    }
    if(!$tune) {
      echo "No Tune: $tuneDir/{$vars['tune']}";
      return '';
    } else if($template=='hymn') {
      $vars['key'] = $tune['key'];
      $vars['transposekey'] = $tune['transposekey'];
      $vars['sop'] = $tune['sop'];
      $vars['alt'] = $tune['alt'];
      $vars['ten'] = $tune['ten'];
      $vars['bas'] = $tune['bas'];
      $vars['raggedlast'] = $tune['raggedlast'];
      $vars['suppressStems'] = $tune['suppressStems'];
      $vars['suppressTimeSignature'] = $tune['suppressTimeSignature'];
      $vars['refrain'] = '';
      $vars['refrainAtBeginning'] = $tune['refrainAtBeginning'];
      $vars['annotation'] = $tune['annotation'];
    } else if($template=='harmonization') {
      mergeTuneHarmonization($vars);
      $template = $vars['template'];
    }
    if($vars['ignoreDurations']) {
      $vars['sop'] = preg_replace('/((\s|^)[a-g]([ei]s)?[\\\',]*)(\d+(\*\d+(\/\d+)?)?)?/', '$1', $vars['sop']);
      $vars['sop'] = str_replace(['\slurUp','\slurDown'], '', $vars['sop']);
      $vars['sop'] = str_replace('^-', '--', $vars['sop']);
    }

    if($template == 'hymn') {
      //Get Text...
      $text = $vars['text-data'];
      if(!$text) {
        $text = loadHymnText($vars['text']);
        $vars['text-data'] = $text;
      }
      $vars['lyrics'] = $text['text'];
      $vars['refrain'] = $text['refrain'];
      $vars['ignoreMelismata'] = $text['ignoreMelismata'];
      if(!$vars['lyrics']) {
        echo "No Text: {$vars['text']}";
      }
    }
  }
  if($template=='hymntune') {
    $template = 'hymn';
  } else if($template=='') {
    return '';
  }
  if($addHeader) {
    $vars['header'] = "\\header {
  poet = \\markup\\large\\italic\\oldStyleNum\"{$vars['user-notes']}\"
  composer = \\markup\\large\\italic\\oldStyleNum\"{$vars['commentary']}\"
}";
  }
  
  if($vars['lyrics']) {
    $actualNumVerses = breakUpVerses($vars,$numVerses,$verseSeparators);
    if(count($verseSeparators) > 0) {
      foreach($verseSeparators as $num) {
        $verseNum = $numbers[$num - 1];
        $vars["lineAfterVerse$verseNum"] = true;
      }
    } else {
      switch($actualNumVerses) {
        case 1:
        case 2:
        case 3:
          break;
        case 4:
          $vars['lineAfterVerseTwo'] = true;
          break;
        case 5:
        case 6:
          $vars['lineAfterVerseThree'] = true;
          break;
        case 7:
        case 8:
        case 9:
        case 10:
          $vars['lineAfterVerseThree'] = true;
          $vars['lineAfterVerseSix'] = true;
          break;
      }
    }
  }
  
  $ly = file_get_contents(ip_masterDir("~ly-templates/$template.ly"));
  $ly = preg_replace_callback(
    '/%{?(\w+)(\?([^%]*)?%?)?(?::([^%]+))?%}?/',
    function($matches) use ($vars) {
      if($vars[$matches[1]]) {
        if(strlen($matches[2])){
          return $matches[3];
        } else {
          return $vars[$matches[1]];
        }
      } else {
        return $matches[4];
      }
    },
    $ly
  );
  if($vars['solidifyDashedSlurs']) {
    $ly = str_replace(array('\slurDashed ','\slurDotted ','\tieDashed ','\tieDotted '),
      array('\slurSolid ','\slurSolid ','\tieSolid ','\tieSolid '),
      $ly);
  } else if($vars['hideDashedSlurs']) {
    $ly = str_replace(array('\slurDashed ','\slurDotted ','\tieDashed ','\tieDotted '),
      array('\slurHide ','\slurHide ','\tieHide ','\tieHide '),
      str_replace(array('\slurSolid ','\slurSolid ','\tieSolid ','\tieSolid '),
        array('\slurShow\slurSolid ','\slurShow\slurSolid ','\slurShow\tieSolid ','\slurShow\tieSolid '),
        $ly));
  }
  if($addIncludeBook) {
    $ly = '\include "lilypond-book-preamble.ly"
' . $ly;
  }
  return $ly;
}
function loadHymnText($filename) {
  foreach(ip_allFiles('hymn-texts') as $dir) {
    if(file_exists("$dir/$filename")) {
      $obj = json_decode(file_get_contents("$dir/$filename"),true);
      return $obj;
    }
  }
  foreach(ip_allFiles('texts/hymn-texts') as $dir) {
    if(file_exists("$dir/$filename")) {
      return array('text' => file_get_contents("$dir/$filename"));
    }
  }
  return FALSE;
}
function loadLy($filename,$loadExtraHymnData = false) {
  foreach (ip_allFiles("engravings/modern/$filename") as $path) {
    if(file_exists($path)) {
      $result = json_decode(file_get_contents($path),true);
      if($result['transposekey'] == '') {
        $result['transposekey'] = $result['key'];
      }
      //echo "1{{$filename}}:TransposeKey: {$result['transposekey']}; Key: {$result['key']};";
      if($loadExtraHymnData || $result['template']=='harmonization') {
        if($result['template']=='hymn' || $result['template']=='harmonization') {
          //Get Tune...
          $tuneDir = 'hymn-tunes';
          if($result['template'] == 'hymn' && $result['layout']!='melody') {
            $tuneDir = 'hymn-harmonizations';
          }
          $result['tune-data'] = loadLy("$tuneDir/{$result['tune']}");
          if($result['template']=='hymn') {
            //Get Text...
            $result['text-data'] = loadHymnText($result['text']);
          }
        }
      }
      if($result['template']=='harmonization') {
        mergeTuneHarmonization($result);
      }
      //echo "2{{$filename}}TransposeKey: {$result['transposekey']}; Key: {$result['key']}";
      return $result;
    }
  }
  return FALSE;
}
function getLyDir($vars) {
  $dir = $vars['dir'];
  if($vars['template']=='harmonization') {
    $tuneName = preg_replace('~^(?:.*/)?([^/]+)\.json~i','$1',$vars['tune']);
    if($tuneName && strpos($dir,$tuneName)===false) {
      $dir .= "/$tuneName";
    }
  }
  return $dir;
}
function getLyFilename($vars) {
  $filename = $vars['filename'];
  if(!$filename) {
    $filename = $vars['name'];
  }
  $filename = normalizeFilename($filename);
  if($vars['useTuneInFileName']) {
    $tune = $vars['tune-data'];
    $tuneDir = 'hymn-tunes';
    if(!$tune) {
      if($vars['template'] == 'hymn' && $vars['layout']!='melody') {
        $tuneDir = 'hymn-harmonizations';
      }
      $tune = loadLy("$tuneDir/{$vars['tune']}");
      $vars['tune-data'] = $tune;
    }
    if($tune['tune-data']) {
      $tuneName = $tune['tune-data']['name'];
    } else {
      $tuneName = $tune['name'];
    }
    $filename .= '_' . normalizeFilename($tuneName);
  }
  return $filename;
}
function saveLy($vars) {
  global $engravingKeys;
  $filename = getLyFilename($vars);
  $vars['filename'] = $filename;
  $dir = ip_userDir('engravings/modern/'.getLyDir($vars));
  if(!is_dir($dir)) {
    mkdir($dir,0777,true);
  }
  $vars = array_intersect_key($vars,$engravingKeys);
  file_put_contents("$dir/$filename.json",json_encode($vars));
}

function lyPsalmToneInfo($vars) {
  $result = Array();
  $sop = $vars['sop'];
  if(0 == preg_match_all('/(?:(?:\\\\rightBracket|Maxima|\\\\mediant|Maior)\s*(?:s\d+\s*)?\\\\recit.*?\\\\acute\s+)([a-g]\S*(.*?))(?=$|\\\\divisio|\\\\finalis|\\\\acute)/',$sop,$matches, PREG_SET_ORDER)) {
    if(0 == preg_match_all('/(?:^.*?\\\\recit.*?(?:\^(?:\\\\markup)?\WI\W|\s+[a-g](?:[ei]s){0,2}\S*)|Maxima\s*.*?\\\\recit\s+[a-g](?:[ei]s){0,2}\d*)(?:\s*(?:r\d*)?)*([a-g](?:[ei]s){0,2}\S*(.*?))(?:$|\\\\divisio|\\\\finalis[^|]*|\\\\acute)/',$sop,$matches, PREG_SET_ORDER)) {
      echo $sop;
    }
  }
  foreach($matches as $m) {
    $result[] = preg_match_all('/(\\\\[a-z]+)?([a-g](?:[ei]s){0,2}|[rs])([,\']*)((128|16|1|2|4|8|32|64)(\.{1,2})?(?:\*(\d+)(?:\/(\d+))?)?)?(\\\\[a-z]+)?/i',$m[1],$matchArray) - 1;
  }
  return $result;
}

function formatTexVerses($verses,$notes,$numbers,$firstVerseNum) {
  if(count($verses)==0) {
    return '';
  }
  $setwidth = '\setlength{\versewidth}{0in}';
  $beginVerse = '\begin{verse}[\versewidth]
\begin{patverse}
';
  $indentpattern = array();
  $extraVerses = '';
  foreach ($verses as $num => $verse) {
    $vnum = $numbers[$num];
    if($vnum) {
      $vnum = applyTexBoldItalics($vnum);
    } else {
      $vnum = ($num + $firstVerseNum) . '.';
    }
    if($notes[$num]) {
      $verse = applyTexBoldItalics(reverseItalics($notes[$num])) . "\n" . $verse;
    }
    $extraVerses .= "\\flagverse{\\garamondLyVerseNumber{{$vnum}}}\n" .
      preg_replace('/\s*\n\s*/', "\\\\\\*\n",
        preg_replace("/\\\\forceItalic\\s+/",'\\textit{',
          str_replace('\\noItalic','}', $verse))) .
      "\\\\![-4pt]\n";
    $forceItalic = false;
    foreach(preg_split('/\s*\n/', $verse) as $line) {
      $indentpattern[] = preg_match('/^\\s/',$line)? 1 : 0;
      if($forceItalic) {
        $line = '\\textit{' . $line;
      }
      $countStart = 0;
      $countStop = 0;
      $line = str_replace('\\forceItalic','',$line,$countStart);
      $line = str_replace('\\noItalic','',$line,$countStop);
      //$count isn't working, so if I really care about the exact length (Rather than the length if the line weren't italic)
      //I will have to call strpos and check whether there were any \\forceItalic commands.
      if($countStart > 0) {
        $noItalicPos = strrpos($line,'}');
        if($noItalicPos !== false) {
          $forceItalicPos = strrpos($line,'\\textit{');
          $forceItalic = $forceItalicPos > $noItalicPos;
        }
      } else if($countStop > 0) {
        $forceItalic = false;
      }
      if($forceItalic) {
        $line .= '}';
      }

      $setwidth .= "%\n\\setlength{\\versewidth}{\\maxof{\\versewidth}{\\widthof{{$line}}}}";
    }
  }
  $indentpattern = '\\indentpattern{' . implode($indentpattern) . '}';
  $extraVerses .= '\end{patverse}
\end{verse}%
';
  return "$setwidth%\n$beginVerse$indentpattern%\n$extraVerses";
}
?>